# -*- coding: utf-8 -*-
import hall_callback
import t_const, t_error, t_cmd, t_wizard
import random, cPickle

#游戏逻辑类，单局游戏的全局数据保存在这里
class CMap(object):
	#构造函数
	def __init__(self, objRoom):
		super(CMap, self).__init__()
		self.objRoom = objRoom				#房间对象的引用，消息发送和写日志用到
		self.objMsgMgr = hall_callback.get_game_room_msgmgr()		#传输对象的引用，消息打包的时候用到
		self.register_recv()		#注册游戏子事件的响应函数
		self.reset()						#初始化游戏内全局数据


	#自我清理的函数，释放此对象前调用
	def clean(self):
		self.reset_map()
		self.reset()
		self.objRoom = None
		self.objMsgMgr = None

	#此函数注册游戏子事件的具体响应函数
	def register_recv(self):
		self.dicEventFunc = {}
		self.dicEventFunc[t_cmd.C_CHOOSE] = self.on_choose
		self.dicEventFunc[t_cmd.C_MOVE] = self.on_move
		self.dicEventFunc[t_cmd.C_STOP] = self.on_stop
		self.dicEventFunc[t_cmd.C_SKILLS] = self.on_skills


	#此函数对游戏内全局数据进行初始化或重置
	def reset(self):
		self.iStatus = t_const.GAME_WAIT		#游戏状态，初始化为准备（非进行游戏）
		self.gametime = -1	# 游戏计时器
		self.iStage = None		#当前关卡，初始化为None
		self.iCurFrame = 0		#当前帧数，初始化为0
		self.objTimeLine = None		#管理怪物和阳光刷新数据的对象，初始化为None
		self.dicTrackSet = {}			#当前关卡的地形数据的字典，key是轨道编号，value是一个代表地形的int，可能为草地、水域或屋顶
		self.dicPlayers = {}			#管理当前游戏内玩家对象的字典，key是玩家的side，value是游戏内玩家对象
		self.dicPlayersuid = {}
		self.iWinScore = 0				#本局的胜利得分
		self.iLoseScore = 0				#本局的失败得分

	#此函数释放和清理游戏内的全局数据，一般在游戏结束的时候调用
	def reset_map(self):
		self.gametime = None
		#清空地形数据字典
		#self.dicTrackSet.clear()

	#此函数生成一个可用的精灵id，并维护精灵id字典，大致算法是对当前已经用到的精灵id进行递增，并加入已用精灵字典，然后返回id
	def generate_id(self, iType):
		pass

	# 初始化游戏地图
	def on_game_init(self, stage, lstPlayer):
		#重置游戏内全局数据
		self.reset()
		#设置游戏状态为游戏中
		self.iStatus = t_const.GAME_PLAYING
		#保存当前关卡key
		self.iStage = stage
		#for player in lstPlayer:
		#	p = t_game_player_s.CGameplayer(player,(0,0))
		#	self.dicPlayers[player.iSide] = p



	#此函数处理游戏开始的相关逻辑
	def on_game_start(self):
		pass

	def player_leave(self,side):
		pass
	#此函数用于处理游戏结束的相关逻辑
	def game_end(self, win):
		#根据玩家当局的具体表现对游戏进行结算，并生成游戏内玩家对象的临时列表
		lstPlayer = []
		for player in self.dicPlayers.itervalues():
			player.on_game_end(win, self.iWinScore,	self.iLoseScore)
			lstPlayer.append(player)

		#游戏状态切换到准备
		self.iStatus = t_const.GAME_WAIT
		#调用房间逻辑的on_game_end函数，处理需要保留的历史数据
		return lstPlayer

	#此函数每个逻辑帧调用一次，处理时间驱动的逻辑
	def logic_frame(self):
		#当前帧数递增
		self.iCurFrame += 1
		pass

	#此函数在客户端发送游戏子事件时由房间逻辑调用，对子事件进行数据解包并根据子事件类型调用具体的子事件处理函数
	def on_game_event(self, iSide, frame, event, data):
		if self.dicEventFunc.has_key(event):
			param = [iSide, ]
			if data:
				param.extend(cPickle.loads(data))
			apply(self.dicEventFunc[event], param)
		pass

	def on_choose(self,pid,model):
		self.send_choose(pid,model)

	def on_move(self,pid):
		pass

	def on_stop(self,pid,street,numb):
		pass

	def on_skills(self,pid,skill):
		pass

#----------------发送事件

	def send_choose(self,pid,model):
		param = (pid,model)
		self.send_game_event(t_cmd.S_CHOOSE,param)

	def send_move(self,pid):
		param = (pid,)
		self.send_game_event(t_cmd.S_MOVE,param)

	def send_stop(self,pid,street,numb):
		param = (pid,street,numb)
		self.send_game_event(t_cmd.S_STOP,param)

	def send_skills(self,pid,skill,target):
		param = (pid,skill,target)
		self.send_game_event(t_cmd.S_SKIILS,param)

	# 所有玩家都初始化完成,发送游戏开始消息
	def send_game_start(self):
		obj = self.objMsgMgr.game_s_game_start_sec(side=1)
		self.objRoom.send_all(obj)


#-------------------------------------------------向客户端广播消息
	#打包并发送游戏子事件的消息，frame：子事件发生的服务端时间帧；event_id：子事件类型；param：子事件具体参数（使用cPickle打包成一个字符串）
	def send_game_event(self, event, param_list):
		_str = cPickle.dumps(param_list)
		obj = self.objMsgMgr.game_s_game_event(frame=self.iCurFrame, event_id=event, param=_str)
		self.objRoom.send_all(obj)

	# 除某人外的其它人
	def send_game_event_other(self, objPlayer, event, param_list):
		_str = cPickle.dumps(param_list)
		obj = self.objMsgMgr.game_s_game_event(frame=self.iCurFrame, event_id=event, param=_str)
		exclude = []
		exclude.append(objPlayer.hid)
		self.objRoom.send_all(obj, exclude)
	# 指定发送玩家
	def send_game_event_p(self, objPlayer, event, param_list):
		_str = cPickle.dumps(param_list)
		obj = self.objMsgMgr.game_s_game_event(frame=self.iCurFrame, event_id=event, param=_str)
		self.objRoom.send_to_user(objPlayer, obj)
		pass
